package net.kleinhenz.norabase.client.datasource;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.widgets.grid.ListGridRecord;

import java.util.Map;

import net.kleinhenz.norabase.shared.SortOrientation;
import net.kleinhenz.norabase.shared.TextMatchStyle;
import net.kleinhenz.norabase.shared.model.Champion;
import net.kleinhenz.norabase.shared.model.FetchResult;
import net.kleinhenz.norabase.shared.model.Rune;

public class ChampionsDS extends RuneDS {

    public ChampionsDS () {

    	super();
    	
    	// add fields taht extends the fieldset in RuneDS
        DataSourceField field;
        field = new DataSourceTextField ("startingAbilitiesString", "Starting Abilities");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);
        
        field = new DataSourceTextField ("upgradeAbilitiesString", "Upgrade Abilities");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);

        field = new DataSourceTextField ("races", "Races");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);

        field = new DataSourceTextField ("classes", "Classes");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);

        field = new DataSourceTextField ("size", "Size");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);
        
        field = new DataSourceIntegerField ("maxrng", "Range (max)");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);

        field = new DataSourceIntegerField ("minrng", "Range (min)");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);

        field = new DataSourceIntegerField ("spd", "Speed");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);

        field = new DataSourceIntegerField ("def", "Defense");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);

        field = new DataSourceIntegerField ("dmg", "Damage");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);

        field = new DataSourceIntegerField ("hp", "Hitpoints");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);
    }

    @SuppressWarnings("unchecked")
	@Override
    protected void executeFetch (final String requestId, final DSRequest request, final DSResponse response) {

    	// aquiring meta data
    	final Map<String, SortOrientation> sortSpec = convertSortSpecifier(request.getSortBy());
        final int startIndex = (request.getStartRow() < 0)?0:request.getStartRow();
        final int endIndex = (request.getEndRow() == null)?-1:request.getEndRow();
        final TextMatchStyle textMatchStyle = convertTextMatchStyle(request.getTextMatchStyle());
        final Map<String, Object> criteria = request.getCriteria().getValues();
        
        // server connection
        ChampionDSServiceAsync service = GWT.create (ChampionDSService.class);
        service.fetch(startIndex, endIndex, sortSpec, textMatchStyle, criteria,
        		new AsyncCallback<FetchResult<Champion>>() {
            public void onFailure(Throwable caught) {
                response.setStatus(RPCResponse.STATUS_FAILURE);
                processResponse(requestId, response);
            }
            public void onSuccess(FetchResult<Champion> result) {
                ListGridRecord[] list = new ListGridRecord[result.size()];
                if (result.size() > 0) {
                    for (int i = 0; i < result.size(); i++) {
                        ListGridRecord record = new ListGridRecord ();
                        copyValues(result.get (i), record);
                        list[i] = record;
                    }
                }
                response.setData(list);
                // IMPORTANT: for paging to work we have to specify size of full result set
                response.setTotalRows(result.fullSize);
                processResponse(requestId, response);
            }
        });
    }

    @Override
    protected void executeUpdate (final String requestId, final DSRequest request, final DSResponse response) {

    	ListGridRecord rec = getEditedRecord(request);
        Champion testRec = new Champion();
        copyValues(rec, testRec);
        ChampionDSServiceAsync service = GWT.create (ChampionDSService.class);
        service.update (testRec, new AsyncCallback<Champion> () {
            public void onFailure (Throwable caught) {
                response.setStatus (RPCResponse.STATUS_FAILURE);
                processResponse (requestId, response);
            }
            public void onSuccess (Champion result) {
                ListGridRecord[] list = new ListGridRecord[1];
                ListGridRecord updRec = new ListGridRecord ();
                copyValues (result, updRec);
                list[0] = updRec;
                response.setData (list);
                processResponse (requestId, response);
            }
        });
    }

    @Override
    protected void copyValues(ListGridRecord from, Rune to) {

    	super.copyValues(from, to);

		Champion toC = (Champion)to;
		// FIXME
		//    	toC.setStartingAbilities(from.getAttributeAsString("startingAbilitiesString"));
		//    	toC.setUpgradeAbilities(from.getAttributeAsString("upgradeAbilitiesString"));
    	toC.setRaces(from.getAttributeAsString("races"));
    	toC.setClasses(from.getAttributeAsString("classes"));
    	toC.setSize(from.getAttributeAsString("size"));
    	toC.setMaxrng(from.getAttributeAsInt("maxrng"));
    	toC.setMinrng(from.getAttributeAsInt("minrng"));
    	toC.setSpd(from.getAttributeAsInt("spd"));
    	toC.setDef(from.getAttributeAsInt("def"));
    	toC.setDmg(from.getAttributeAsInt("dmg"));
    	toC.setHp(from.getAttributeAsInt("hp"));
    }
    
    @Override
	protected void copyValues(Rune from, ListGridRecord to) {

		super.copyValues(from, to);

		Champion fromC = (Champion)from;
		to.setAttribute("startingAbilitiesString", fromC.getStartingAbilitiesString());
		to.setAttribute("upgradeAbilitiesString", fromC.getUpgradeAbilitiesString());
		to.setAttribute("races", fromC.getRaces());
		to.setAttribute("classes", fromC.getClasses());
		to.setAttribute("size", fromC.getSize());
		to.setAttribute("maxrng", fromC.getMaxrng());
		to.setAttribute("minrng", fromC.getMinrng());
		to.setAttribute("spd", fromC.getSpd());
		to.setAttribute("def", fromC.getDef());
		to.setAttribute("dmg", fromC.getDmg());
		to.setAttribute("hp", fromC.getHp());
    }
}
